﻿using Engine;
using Game.NetWork;
using Game.NetWork.Packages;
using Game.Server;
using Game.Server.Event;
using Game.Server.PlayerEvent;
using GameEntitySystem;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using static Game.Server.Plugins.AA;



namespace Game.Server.Plugins
{
    public class AA : ServerPlugin, ICreatureSpawnEventHandle
    {


        public static readonly string 路径 = "掉落物.json";

        public string GetProcessName = "掉落物";

        public class 掉落物数据
        {
            public int 方块id { get; set; }
            public int 数量 { get; set; }
            public float 掉落频率 { get; set; }
        }

        public class Point3v
        {
            public Point3v(int x1, int y1, int z1)
            {
                x = x1;
                y = y1;
                z = z1;
            }

            public Point3v ff(int x1, int y1, int z1)
            {
                return new Point3v(x, y, z);
            }

            public int x { get; set; }
            public int y { get; set; }
            public int z { get; set; }
        }

        public static Dictionary<string, Dictionary<string, 掉落物数据>> DropTable = new Dictionary<string, Dictionary<string, 掉落物数据>>();

        public static Dictionary<string, Dictionary<Vector3, 掉落物数据>> DropTable1 = new Dictionary<string, Dictionary<Vector3, 掉落物数据>>();

        public override int Version => 1;

        public override string Name => "掉落物刷新插件(四氧化二不落制作)";

        public SubsystemTime subsystemTime;

        public SubsystemPickables subsystemPickables;

        public byte FirstLevel => 100;

        public override void Initialize()
        {
            CreatureSpawnEventManager.AddObject(this);
            建立();
            从JSON加载数据();
        }

        public void 建立()
        {
            if (File.Exists(路径))
            {
                Log.Information("配置文件已创建");
            }
            else
            {
                var tempDict = new Dictionary<string, Dictionary<string, 掉落物数据>>
                {
                    {
                        GetProcessName,
                        new Dictionary<string, 掉落物数据>
                        {
                            { "1,100,3", new 掉落物数据{ 方块id = 1, 数量 = 1, 掉落频率 = 0.5f } },
                            { "1,120,4", new 掉落物数据{ 方块id = 2, 数量 = 2, 掉落频率 = 0.5f } }
                        }
                    }
                };


                string json1 = JsonConvert.SerializeObject(tempDict);
                File.WriteAllText(路径, json1, Encoding.UTF8);
                Log.Information("配置文件已创建，配置已加载");
            }
        }

        public override void Load()
        {

            subsystemTime = GameManager.Project.FindSubsystem<SubsystemTime>();
            subsystemPickables = GameManager.Project.FindSubsystem<SubsystemPickables>();
            Log.Information("读取子系统成功");
        }

        public override void Save()
        {

        }

        public static void 写入数据(int 方块id, int 数量, float 掉落频率, Vector3 位置)
        {
            // 1. 更新 DropTable1（内存中的 Vector3 字典）
            if (!DropTable1.ContainsKey("掉落物"))
            {
                Log.Error("DropTable1 字典key掉落物不存在");
            }
            else
            {
                DropTable1["掉落物"][位置] = new 掉落物数据
                {
                    方块id = 方块id,
                    数量 = 数量,
                    掉落频率 = 掉落频率
                };

                // 2. 更新 DropTable（用于JSON的字符串坐标字典）
                string coordKey = $"{(float)位置.X},{(float)位置.Y},{(float)位置.Z}";

                if (!DropTable.ContainsKey("掉落物"))
                {
                    DropTable["掉落物"] = new Dictionary<string, 掉落物数据>();
                }
                DropTable["掉落物"][coordKey] = new 掉落物数据
                {
                    方块id = 方块id,
                    数量 = 数量,
                    掉落频率 = 掉落频率
                };

                // 3. 立即保存到JSON文件
                保存到JSON();
            }
        }

        private static void 保存到JSON()
        {
            try
            {
                string json = JsonConvert.SerializeObject(DropTable, global::Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(路径, json, Encoding.UTF8);
                Log.Information("数据已保存到JSON文件");
            }
            catch (Exception ex)
            {
                Log.Error($"保存失败: {ex.Message}");
            }
            从JSON加载数据();
        }

        public static void 删除数据(Vector3 位置)
        {
            // 1. 从 DropTable1（内存中的 Vector3 字典）删除掉落物
            if (!DropTable1.ContainsKey("掉落物"))
            {
                Log.Error("DropTable1 字典key掉落物不存在");
            }
            else
            {
                DropTable1["掉落物"].Remove(位置);

                // 2. 从 DropTable（用于JSON的字符串坐标字典）删除掉落物
                string coordKey = $"{(float)位置.X},{(float)位置.Y},{(float)位置.Z}";

                if (!DropTable.ContainsKey("掉落物"))
                {
                    Log.Error("DropTable 字典key掉落物不存在");
                }
                else
                {
                    DropTable["掉落物"].Remove(coordKey);

                    // 3. 立即保存到JSON文件
                    保存到JSON();
                }
            }
        }

        private static void 从JSON加载数据()
        {
            try
            {
                string json = File.ReadAllText(路径); // 读取JSON文件
                DropTable = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, 掉落物数据>>>(json);
                Console.WriteLine("从JSON文件加载数据成功");

                // 初始化DropTable1
                DropTable1.Clear();

                // 遍历所有掉落物数据
                foreach (var category in DropTable)
                {
                    string categoryName = category.Key;
                    Console.WriteLine($"分类: {categoryName}");

                    // 为当前分类创建新的Vector3字典
                    Dictionary<Vector3, 掉落物数据> vectorDrops = new Dictionary<Vector3, 掉落物数据>();

                    foreach (var entry in category.Value)
                    {
                        // 获取坐标字符串（如 "1,2,3"）
                        string coordinateString = entry.Key;

                        try
                        {
                            // 分割字符串并转换为Vector3
                            string[] parts = coordinateString.Split(',');
                            if (parts.Length == 3)
                            {
                                float x = float.Parse(parts[0]);
                                float y = float.Parse(parts[1]);
                                float z = float.Parse(parts[2]);
                                Vector3 position = new Vector3(x, y, z);

                                // 保存掉落物数据到新字典
                                vectorDrops[position] = entry.Value;
                                Console.WriteLine($"成功转换坐标 {coordinateString} 为 Vector3: {position}");
                            }
                            else
                            {
                                Console.WriteLine($"无效的坐标格式: {coordinateString}");
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"转换坐标失败 {coordinateString}: {ex.Message}");
                        }
                    }

                    // 将转换后的分类数据添加到DropTable1
                    DropTable1[categoryName] = vectorDrops;
                }
                foreach (var category in DropTable1)
                {
                    Console.WriteLine($"分类: {category.Key}");
                    foreach (var dropItem in category.Value)
                    {
                        Console.WriteLine($"  分类: {category.Key} 位置: {dropItem.Key} 掉落频率: {dropItem.Value.掉落频率} 掉落物数量: {dropItem.Value.数量} 掉落物ID: {dropItem.Value.方块id}");
                        // 如果你使用Serilog的Log.Information
                        Log.Information($"分类: {category.Key} 位置: {dropItem.Key} 掉落频率: {dropItem.Value.掉落频率} 掉落物数量: {dropItem.Value.数量} 掉落物ID: {dropItem.Value.方块id}");
                    }
                    Console.WriteLine($"该分类共有 {category.Value.Count} 个掉落物");
                }

                Console.WriteLine("坐标转换完成，数据已存入DropTable1");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"加载JSON文件失败: {ex.Message}");
                Console.WriteLine(ex.ToString());
            }
        }

        public bool Update(SubsystemCreatureSpawn subsystemCreatureSpawn, float dt)
        {

            if (控制系统.掉落物系统状态)
            {
                // 遍历所有掉落物数据fa
                foreach (var category in DropTable1) 
                {
                    foreach (var dropItem in category.Value)
                    {
                        if (dropItem.Value != null && dropItem.Key != null && category.Key == "掉落物")
                            if (subsystemTime.PeriodicGameTimeEvent(dropItem.Value.掉落频率, 0.0))
                            {
                                Vector3 position = dropItem.Key;
                                position.X += 0.5f;
                                position.Y += 0.5f;
                                position.Z += 0.5f;
                                Pickable pickable = subsystemPickables.CreatePickable(null, dropItem.Value.方块id, dropItem.Value.数量, position, default, default);
                                pickable.Net_ToRemove = true;
                                CommonLib.Net.QueuePackage(new PickablePackage(pickable, PickablePackage.PickType.Create));// 发送购买物品的包裹
                            }
                    }
                }
            }



            return true;
        }

        public void OnEntityAdded(SubsystemCreatureSpawn subsystemCreatureSpawn, Entity entity)
        {

        }

        public void OnEntityRemoved(SubsystemCreatureSpawn subsystemCreatureSpawn, Entity entity)
        {
        }

        public void OnPlayerSpawned(PlayerData playerData, Entity playerEntity, Vector3 position)
        {

        }

        public void InitCreatureTypes(SubsystemCreatureSpawn subsystemCreatureSpawn, List<SubsystemCreatureSpawn.CreatureType> creatureTypes)
        {

        }
    }

    public class 控制系统 : AbstractProcessCmd
    {
        public override string Cmd => "pickables";

        public override string Introduce => "/pickables    ----查看所有掉落物命令";

        public override int AuthLevel => 1000;

        public static bool 掉落物系统状态 = false;

        public override DisplayType Display => DisplayType.All;

        private void SendHelpMessage()
        {
            string text = "\n/pickables zt off或on  ------打开或关闭掉落物系统 \n /pickables add 方块ID 数量 掉落频率 x y z  ------添加掉落物 \n/pickables display      ------查看掉落物列表 \n /pickables undo x y z  ------删除掉落物 \n/pickables uplevel 等级  ------提升等级";
            base.SendMessage("查看所有掉落物命令=====>>>", text);
        }

        public void DisplaySmallMessageNet(ComponentPlayer componentPlayer, string text)  // 小消息方法
        {
            var messagePackget = new MessagePackage(null, text, 0, null);
            messagePackget.To = componentPlayer.PlayerData.Client;
            CommonLib.Net.QueuePackage(messagePackget);
        }

        public override void ProcessCmd()
        {

            if (m_messageDatas.Length <= 1)
            {
                SendHelpMessage();
                return;
            }

            if (m_messageDatas[1] == null)
            {
                SendHelpMessage();
            }

            bool 状态 = true;
            bool flag = GameManager.Project == null;
            bool flag2 = flag;
            if (flag2)
            {
                base.SendMessage("掉落物命令器=====>>>", "你需要先开始游戏");
            }
            else
            {
                ComponentPlayer componentPlayer = this.m_client.PlayerData.ComponentPlayer;
                if (m_messageDatas[1] == "zt")
                {
                    //第一个指令
                    if (m_messageDatas[2] == "on")
                    {
                        掉落物系统状态 = true;
                        DisplaySmallMessageNet(componentPlayer, "掉落物系统已开启");
                        
                        Log.Information("掉落物系统已开启");
                    }
                    else if (m_messageDatas[2] == "off")
                    {
                        掉落物系统状态 = false;
                        DisplaySmallMessageNet(componentPlayer, "掉落物系统已关闭");
                        Log.Information("掉落物系统已关闭");
                    }
                    else SendHelpMessage();
                    //第一个指令
                }
                else if (m_messageDatas[1] == "add")
                {
                    int 数量=0, 方块id=0, x = 0, y = 0, z = 0;
                    float 掉落频率=10f;
                    Vector3 位置 = Vector3.Zero;

                    try
                    {
                        方块id = int.Parse(m_messageDatas[2]);
                    }
                    catch
                    {
                        状态 = false;
                        SendHelpMessage();
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的方块ID(整数)");
                    }
                    try
                    {
                        数量 = int.Parse(m_messageDatas[3]);
                    }
                    catch
                    {
                        状态 = false;
                        SendHelpMessage();
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的数量(整数)");
                    }
                    try
                    {
                        掉落频率 = float.Parse(m_messageDatas[4]);
                    }
                    catch
                    {
                        状态 = false;
                        SendHelpMessage();
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的掉落频率(小数)");
                    }
                    try
                    {
                        x = int.Parse(m_messageDatas[5]);
                        y = int.Parse(m_messageDatas[6]);
                        z = int.Parse(m_messageDatas[7]);
                        位置 = new Vector3(x, y, z);
                    }
                    catch
                    {
                        状态 = false;
                        SendHelpMessage();
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的坐标(整数)");
                    }
                    if (状态)
                    {
                        DisplaySmallMessageNet(componentPlayer, "成功修改");
                        写入数据(方块id, 数量, 掉落频率, 位置);
                    }
                }
                else if (m_messageDatas[1] == "display")
                {
                    foreach (var category in DropTable1)
                    {
                        Console.WriteLine($"分类: {category.Key}");
                        foreach (var dropItem in category.Value)
                        {
                            DisplaySmallMessageNet(componentPlayer,$"  分类: {category.Key} 位置: {dropItem.Key} 掉落频率: {dropItem.Value.掉落频率} 掉落物数量: {dropItem.Value.数量} 掉落物ID: {dropItem.Value.方块id}");
                            // 如果你使用Serilog的Log.Information                           
                        }
                        DisplaySmallMessageNet(componentPlayer,$"该分类共有 {category.Value.Count} 个掉落物");
                    }
                }
                else if(m_messageDatas[1] == "undo")
                {
                    int x, y, z; bool flag3 = true;
                    Vector3 vector3 = new Vector3(0, 0, 0);
                    try
                    {
                        x = int.Parse(m_messageDatas[2]);
                        y = int.Parse(m_messageDatas[3]);
                        z = int.Parse(m_messageDatas[4]);
                        vector3 = new Vector3(x, y, z);
                    }
                    catch(Exception ex)
                    {
                        flag3 = false;
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的坐标(整数)");
                        Log.Error(ex.Message);
                    }

                    if (flag3)
                    {
                        删除数据(vector3);
                        DisplaySmallMessageNet(componentPlayer, "成功删除掉落物");
                    }

                }
                else if (m_messageDatas[1] == "uplevel")
                {
                    int level = 0; bool g = true;
                    try
                    {
                        level = int.Parse(m_messageDatas[2]);
                    }
                    catch(Exception ex)
                    {
                        g = false;
                        DisplaySmallMessageNet(componentPlayer, "请输入正确的等级(整数)");
                    }
                    if (g) 
                    {
                        UpLevel(componentPlayer, level);
                        DisplaySmallMessageNet(componentPlayer, "成功提升等级");
                    }

                }
                if (m_messageDatas[1] == "admin")
                {
                    管理员创造模式(componentPlayer);
                }

            }


        }

        public void UpLevel(ComponentPlayer componentPlayer, int level)
        {
            componentPlayer.PlayerData.Level = level;
            CommonLib.Net.QueuePackage(new ComponentPlayerPackage(componentPlayer.PlayerData, (int)componentPlayer.PlayerData.Level, true, componentPlayer.PlayerData.Level));
        }

        public void 管理员创造模式(ComponentPlayer componentPlayer)
        {
          SubsystemGameInfo subsystemGameInfo = componentPlayer.Project.FindSubsystem<SubsystemGameInfo>();
            subsystemGameInfo.WorldSettings.GameMode = GameMode.Creative;
        }

    }

}

